package com.cskaoyan.javase.oop3._2inner._3local._1basic;

import javax.print.attribute.standard.PrinterURI;

/**
 * 局部内部类的访问特点,要注意以下两点:
 *
 * 1.局部内部类访问外围类成员仍然是任意访问,不受权限限制
 * 但是外围类要想访问局部内部类,必须在装有局部内部类的作用域内部
 * 2.外部类已经完全无法直接访问到局部内部类了。
 *
 * 局部内部类的访问特点
 * 局部内部类的访问特点，我们仍然主要从以下几个角度研究：
 * 1.局部内部类内部访问外围类
 *      这个访问首先需要外围类对象
 *      而且访问的位置是: 局部内部类当中的成员方法或者构造器
 *
 *      但是局部内部类和成员内部类不同的点在于
 *          外围类成员方法中的局部内部类和外围类静态方法中的局部内部类是不同的
 *
 * 外围类的成员方法中的局部内部类(可以看成是一个成员内部类,因为它会持有外围类对象的引用)
 *      成员方法中是隐含this传参,指向当前对象的
 *      所以外围类的成员方法中的局部内部类对象
 *          会持有外围类对象的引用
 *
 * 外围类的静态成员方法中的局部内部类
 * 静态方法中没有任何对象,所以外围类的静态成员方法中的局部内部类对象,不会持有任何外围类对象的引用
 * 这时如果还想访问外围类成员,只需要创建它的对象即可!
 *
 * 2.外围类访问局部内部类成员
 *      首先这里需要创建局部内部类对象
 *      但是直接访问局部内部类必须在装有局部内部类的作用域内部类访问
 *      其他位置是访问不到的
 *
 * 3.外部类访问局部内部类成员
 *      也是无法直接访问局部内部类的
 *
 * 4.局部内部类访问外部类成员
 *      可以,但是受权限限制
 *
 * 补充:
 * 局部内部类在作用域的外部就无法直接被访问了,但是局部内部类的对象仍然可以在作用域外部被访问
 * 方法内部的局部内部类,可以通过方法的返回值将局部内部类对象返回出去.
 *
 * @since 17:36
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        EnclosedClazz ec = new EnclosedClazz();
        ec.test();
        EnclosedClazz.testStatic();

        // 父类引用限制子类对象访问范围
        Object o = ec.testReturn();
    }
}

class EnclosedClazz {
    int a;
    private int b = 10;
    static int c = 20;
    static final int D = 30;

    Object testReturn(){
        class Inner{
            int a = 10;
            private int b = 20;
        }
        return new Inner();
    }


    // 外围类的成员方法
    public void test() {
        // 局部位置,定义局部内部类
        class Inner {
            int a;
            private int b = 10;
            static final int D = 30;

            // 外围类成员方法中的局部内部类的成员方法
            public void testInner(int b) {
                /*
                    该方法中有两个对象
                    1.自身局部内部类对象,用this指向
                    2.外围类对象,用外围类类名.this指向
                    这里的使用就非常类似于成员内部类
                    因为这里也会持有外围类对象的引用
                  */
                System.out.println(a);
                System.out.println(EnclosedClazz.this.a);
                System.out.println(b);
                System.out.println(this.b);
                System.out.println(EnclosedClazz.this.b);
            }
        }
        Inner i = new Inner();
        i.testInner(666);
        System.out.println(i.b);
    }

    // 外围类的静态成员方法
    public static void testStatic() {
        // 外围类的静态成员方法中的局部内部类
        class Inner {
            int a;
            private int b = 10;
            static final int D = 30;

            // 外围类的静态成员方法中的局部内部类中的成员方法
            public void testInner() {
                System.out.println(a);
                // System.out.println(EnclosedClazz.this.a);
                EnclosedClazz ec = new EnclosedClazz();
                System.out.println(ec.a);
            }
        }
        Inner i = new Inner();
        i.testInner();
    }
}